package com.example.clientsideapplication;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;

import android.app.ActivityManager;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;

public class TrasmissionService extends IntentService {

	private final static String MY_PREFERENCES = "myAppPref";
	private Socket socket;
	private Position myPosition;
	private ObjectOutputStream outputWriter;
	private ObjectInputStream inputReader;
	private double latitude, longitude;
	private SharedPreferences pref;
	private ArrayList<Entry<Merchant, Offer>> offer;
	private ArrayList<String> preferences;
	private int meters;
	private DataPackage outputMessage, incomingmessage;
	private Entry<Position, Entry<ArrayList<String>, Integer>> outputEntry;
	private final String GEO_ACTION = "android.intent.action.GEO_ACTION";
	private boolean casalinghi;
	private boolean alimentari;
	private boolean informatica;
	private boolean vestiario;
	private boolean telefonia;
	private String casalinghiString;
	private String alimentariString;
	private String informaticaString;
	private String vestiarioString;
	private String telefoniaString;
	private ActivityManager activityManager;
	private List<ActivityManager.RunningTaskInfo> taskInfo;
	private ComponentName componentInfo;
	private boolean mainActivityVisible = false;
	private Context context;
	private String cachingOfferFileName = "cachingOfferFile";
	private FileOutputStream fileOutputStream;
	private ObjectOutputStream objectOutputStream;
	private FileInputStream fileInputStream;
	private ObjectInputStream objectInputStream;
	private ArrayList<Entry<Merchant, Offer>> offerArrayCacheList = new ArrayList<Entry<Merchant, Offer>>();
	private boolean isNotEquivalentToCachedList = true;
	private SharedPreferences.Editor editor;
	
	public TrasmissionService() {
		super("TrasmissionService");
	}
	
	 @Override
	 public IBinder onBind(Intent intent) {
	   return null;
	 }

	@Override
	protected void onHandleIntent(Intent intent) {
		// TODO Auto-generated method stub
		String serverAddress = intent.getStringExtra("serverAddress");
		int serverSocket = intent.getIntExtra("serverSocket", 21111);
		latitude = intent.getDoubleExtra("latitude", 0);
		longitude = intent.getDoubleExtra("longitude", 0);

		try {
			socket = new Socket(serverAddress, serverSocket);
			outputWriter = new ObjectOutputStream(socket.getOutputStream());
			inputReader = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));

			pref = getSharedPreferences(MY_PREFERENCES, Context.MODE_PRIVATE);

			casalinghi = pref.getBoolean("cb1", false);
			alimentari = pref.getBoolean("cb2", false);
			informatica = pref.getBoolean("cb3", false);
			vestiario = pref.getBoolean("cb4", false);
			telefonia = pref.getBoolean("cb5", false);
			meters = pref.getInt("meters", 0);

			if (casalinghi)
				casalinghiString = "Casalinghi";

			if (alimentari)
				alimentariString = "Alimentari";

			if (informatica)
				informaticaString = "Informatica";
						
			if (vestiario)
				vestiarioString = "Vestiario";
						
			if(telefonia)
				telefoniaString = "Telefonia";

			preferences = new ArrayList<String>();
			preferences.add(casalinghiString);
			preferences.add(alimentariString);
			preferences.add(informaticaString);
			preferences.add(vestiarioString);
			preferences.add(telefoniaString);
						
			myPosition = new Position(latitude, longitude);
			outputEntry = new SimpleEntry<Position, Entry<ArrayList<String>, Integer> >(myPosition, new SimpleEntry(preferences, meters));
			outputMessage = new DataPackage(7, outputEntry);
			outputWriter.writeObject(outputMessage);
			incomingmessage = (DataPackage) inputReader.readObject();   
			
			offer = (ArrayList<Entry<Merchant, Offer>>) incomingmessage.getDataPackage();			
			
			if(offer.size()!=0){
				
				context = getApplicationContext();
				
				try{
					fileInputStream = context.openFileInput(cachingOfferFileName);
					objectInputStream = new ObjectInputStream(fileInputStream);
					offerArrayCacheList = (ArrayList<Entry<Merchant, Offer>>) objectInputStream.readObject();
					objectInputStream.close();
				}catch (FileNotFoundException e){
					;
				}catch (IOException e) {
					;
				}
				
				if(offerArrayCacheList.size()!=0 && (offerArrayCacheList.size()==offer.size())){
					int i = 0;
					
					for(Entry<Merchant, Offer> singleEntry : offerArrayCacheList){
						if(	(singleEntry.getValue().getStartDate().equals(offer.get(i).getValue().getStartDate())) &&
							(singleEntry.getValue().getEndDate().equals(offer.get(i).getValue().getEndDate())) &&
							(singleEntry.getValue().getProductPrice()==offer.get(i).getValue().getProductPrice()) ){
							isNotEquivalentToCachedList = false;
							i = i + 1;
						}
						else{
							isNotEquivalentToCachedList = true;
						}
					}
				}
				else{
					fileOutputStream = context.openFileOutput(cachingOfferFileName, Context.MODE_PRIVATE);
					objectOutputStream = new ObjectOutputStream(fileOutputStream);
					objectOutputStream.writeObject(offer);
					objectOutputStream.close();
				
					editor = pref.edit();
					editor.putBoolean("cacheArrayExists", true);
					editor.commit();
				}
				
				activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
				taskInfo = activityManager.getRunningTasks(1);

				componentInfo = taskInfo.get(0).topActivity;
			
				if (componentInfo
						.getClassName()
						.toString()
						.equals("com.example.clientsideapplication.MainActivity")) {
					mainActivityVisible = true;
				}
			
				if(mainActivityVisible && isNotEquivalentToCachedList){
					Intent offerIntent = new Intent();
					offerIntent.setAction(GEO_ACTION);
				
					offerIntent.putExtra("offer", offer);
					sendBroadcast(offerIntent);
				}
				else if(isNotEquivalentToCachedList){
					int SIMPLE_NOTIFICATION_ID = 1;
					String notificationText = "Nuove offerte disponibili:";
					String notificationTitle = "GeoCommerce";
					long[] vibraPattern = { 0, 500, 250, 500 };
					Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
				
					NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

					NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
							.setSmallIcon(R.drawable.ic_launcher)
							.setAutoCancel(true)
							.setVibrate(vibraPattern)
							.setSound(alarmSound)
							.setPriority(Notification.FLAG_HIGH_PRIORITY);
					
					NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
					
					inboxStyle.setBigContentTitle(notificationTitle);
					inboxStyle.addLine(notificationText);
					
					if (offer.size() > 3){
						for (int i = 0; i < 3; i++) {
							inboxStyle.addLine(offer.get(i).getValue().getProductName() + " - " + offer.get(i).getValue().getProductPrice() + " euro");
						}
						inboxStyle.addLine("Clicca per scoprire gli altri prodotti!");
					}
					else{
						for (int i = 0; i < offer.size(); i++) {
							inboxStyle.addLine(offer.get(i).getValue().getProductName() + " - " + offer.get(i).getValue().getProductPrice() + " euro");
						}
					}
					
					mBuilder.setStyle(inboxStyle);

					Intent viewNotificationIntent = new Intent(context, ViewClientOfferActivity.class);
				
					viewNotificationIntent.putExtra("notificationType", "Server Notification");
					viewNotificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					viewNotificationIntent.putExtra("offer", offer);
				
					PendingIntent resultPendingIntent = PendingIntent.getActivity(context, 0,
									viewNotificationIntent,
									PendingIntent.FLAG_CANCEL_CURRENT);
					mBuilder.setContentIntent(resultPendingIntent);

					notificationManager.notify(SIMPLE_NOTIFICATION_ID, mBuilder.build());
				}
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e){
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e){
			e.printStackTrace();
		}
	}
	
}
